<template>
  <el-select
    v-model="value"
    :disabled="disabled"
    :size="size"
    :multiple="multiple"
    :filterable="filterable"
    :clearable="clearable"
    :collapse-tags="collapseTags"
    :placeholder="plzSelect?$t('message.plzSelect'):(labelAll?labelAll:$t('common.text.all'))"
    style="width: 100%;"
    :popper-class="showBar ? 'edu-dict-select': ''"
    @change="handleChange"
    v-clearreadonly>
    <el-row class="select-tool-bar" v-if="showBar">
      <el-col :span="12">
        <el-button size="mini" @click="checkAll" style="width: 100%;">{{$t('common.btn.checkAll')}}</el-button>
      </el-col>
      <el-col :span="12">
        <el-button size="mini" @click="cancelAll" style="width: 100%;">{{$t('common.btn.cancelAll')}}</el-button>
      </el-col>
    </el-row>
    <el-option v-if="showAll"
               :label="labelAll?labelAll:$t('common.text.all')"
               :value="valueAll" />
    <el-option v-for="item in filterData"
               :key="item.value"
               :label="showCode?`${item.label}(${item.value})`:item.label"
               :value="item.value" />
  </el-select>
</template>
<script>
/**
 * 字典下拉框组件
 */
export default {
  name: 'dict-select',
  props: {
    value: {
      required: true
    },
    disabled: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    },
    filterable: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: ''
    },
    showAll: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: true
    },
    collapseTags:{
      type: Boolean,
      default: true
    },
    data: {
      type: Array,
      default: []
    },
    plzSelect: { // 用于展示placeholder的默认值 而不是 “全部”
      type: Boolean,
      default: false
    },
    labelAll: {
      type: String
    },
    valueAll: {
      default: ""
    },
    showCode: { // 是否同时显示code
      type: Boolean,
      default: false
    },
    include:{ // 包含的code 展示在这里 null 则展示全部，即在include又在exclude 以include为准
      type: Array
    },
    exclude:{ // 排除的code
      type: Array
    },
    showToolBar: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
    }
  },
  computed:{
    showBar(){
      return this.multiple && this.showToolBar;
    },
    filterData(){
      // console.log(this.data);
      // 数据字典一般为字符串形式
      if (this.include){
        this.include = this.include.map(item=>item+"");
      }else if (this.exclude){
        this.exclude = this.exclude.map(item=>item+"");
      }
      let filter = this.data.filter(item=>{
        if (this.include){
          return this.include.includes(item.value) //过滤必须在include集合中, 数据字典一般为字符串形式
        }else if (this.exclude){
          return !this.exclude.includes(item.value) // 过滤
        }
        return true;
      });
      return filter;
    }
  },
  mounted() {
  },
  created() {
    if (this.multiple && !Array.isArray(this.value)) {
      this.$emit("input", []);
    }
    if (!this.multiple && Array.isArray(this.value)) {
      this.$emit("input", "");
    }
  },
  methods: {
    handleChange(val) {
      if(this.multiple === true && this.showAll === true){
        /*
          this.oldSelect 上一次选择结果
          val此次操作后的结果
          includes("") 判断是否包含全部选项
        */
        if(!this.oldSelect && val.includes("")){
          let newVal = this.filterData.map(el=>{
            return el.value
          })
          val = ["",...newVal]
        }else if(!this.oldSelect.includes("") && val.includes("")){
          // 全部选项被选中
          let newVal = this.filterData.map(el=>{
            return el.value
          })
          val = ["",...newVal]
        }else if(!this.oldSelect.includes("") && !val.includes("")){
          //  全部选项未被选中时，oldSelect存在且oldSelect长度与原数组长度相同，则说明选择了除全部之外的所有数据，此时只增加全部选项即可
            if(val.length == this.filterData.length){
              val = ["",...val]
            }
        }else if(this.oldSelect.includes("") && !val.includes("")){
          // 反选
          val = []
        }else if(val.length-1 != this.filterData.length){
          val.splice(val.indexOf(""),1)
        }
      }
      this.$emit("input", val);
      //if(!_.isEqual(val, this.value)){
        this.$emit('change', val)
      //}
      this.oldSelect = val
    },
    checkAll(){
      const val = [];
      _.forEach(this.filterData, (d)=>{
        val.push(d.value);
      });
      this.handleChange(val);
    },
    cancelAll(){
      this.handleChange([]);
    }
  }
}

</script>

<style scoped lang="scss">

</style>
